package ru.athena.runTool;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import ru.athena.runTool.Model.CodeTreeProcessParam;
import ru.athena.runTool.Model.OperationShowProgress;
import ru.athena.runTool.Model.PrintStreamCapturer;
import ru.athena.runTool.Model.RunToolModel;

public class RunToolController {
	private Connection		conn = null;
	private RunToolModel 	model_;
	private RunToolView 	view_;
	private AppProperties 	prop_;	

	RunToolController(RunToolModel model, RunToolView view, AppProperties prop ) {
		this.prop_ = prop;		
		model_ = model;
		view_ = view;
		// ... Add listeners to the view.
		view_.addParseActionListener(new ParseListener());
		view_.addParseDirActionListener(new ParseDirListener());		
		view_.addRunActionListener(new RunListener());		
		view_.addExitActionListener(new ExitActionListener());
		view_.addStoreListener( new StoreListener());
		
		System.setOut( 
				PrintStreamCapturer.getPrintStream( view_.getSystemOutTextArea()) );
		System.setErr( 
				PrintStreamCapturer.getPrintStream( view_.getSystemErrTextArea()) );
	}

	private class ExitActionListener implements ActionListener {
	    public void actionPerformed(ActionEvent e) {
	    	System.exit(0);
	    }
		
	}
	private Connection getConnection() throws SQLException {
		String				connString = view_.getConnectionString();
		String 				userName = view_.getUserName();
		prop_.setConnectionString( connString );
		prop_.setUserName( userName );

		// otherwise get "java.sql.SQLException: No suitable driver"
		DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
			
		conn = DriverManager.getConnection( connString, userName, view_.getPasword() );

		return conn;
	}

	private void closeConnection() {
		if (conn != null) {
			try {
				conn.close();				
			} catch (Exception e) {
				System.out.println( "Failed to close connection...");
				e.printStackTrace();
			}
		}
	}	

	private class StoreListener implements ActionListener {
		public void actionPerformed( ActionEvent e ) {
			DefaultTreeModel	codeTree = view_.getTreeModel();
			try {
				model_.storeCodeTree(
						new CodeTreeProcessParam(
								new TreePath(codeTree.getRoot()), 
								getConnection(), 
								new OperationShowProgress( view_)) );
			
			} catch (Exception se) {
				view_.addStatusText( se.getMessage() );
				closeConnection();
			}			
		}

		
	}

	
	private class ParseListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String scriptPath = "";
			try {
				scriptPath = view_.getChoosedPath();
				view_.activateStartButton(false);
				// store file name
				prop_.setFilePath( scriptPath );
			
				view_.setRootNode( model_.buildTreeForFile( scriptPath ) );
				view_.activateStartButton(true);

			} catch (Exception rtex) {
				view_.showError("Runtime error: '" + rtex.toString() + "'");
			}
		}
	}
	
	private class ParseDirListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String scriptDir = "";
			try {
				scriptDir = view_.getChoosedPath();
				view_.activateStartButton(false);
				// store file name
				prop_.setFilePath( scriptDir );
			
				view_.setRootNode( model_.buildTreeForDir( scriptDir ) );
				view_.activateStartButton(true);

			} catch (Exception rtex) {
				view_.showError("Runtime error: '" + rtex.toString() + "'");
			}
		}
	}
	private class RunListener implements ActionListener {
		public void actionPerformed( ActionEvent e ) {
			TreePath	startPath = view_.getTreeSelectionPath();
			
			try {
				model_.executeCodeTree( 
						new CodeTreeProcessParam(
								startPath, 
								getConnection(), 
								new OperationShowProgress( view_)) );
				
			} catch (Exception se) {
				view_.addStatusText( se.getMessage() );
				closeConnection();
			}
		}	
	}
}
